﻿package com.duartepeixinho.pTween.core
{
	
	/**
	 * Tween Equations
	 * @author Robert Penner / http://www.robertpenner.com/easing_terms_of_use.html
	 * 
	 * @author 		Duarte Peixinho
	 * @version		PTween 1.1
	 */
	public class tweenEquations 
	{
		
		public function tweenEquations() 
		{
			trace("tweenEquantions is a static class and should not be instantiated.");
		}
		
		/**
		 * Equations
		 * @param	transition	String		Easing Option
		 * @param	time		Number		Current Time
		 * @param	init		Number		Initial Position
		 * @param	change		Number		Initial - Final
		 * @param	duration	Number		Easing Duration
		 * @return				Number		Value
		 */
		public static function calculateEquation(transition:String, time:Number, init:Number, change:Number, duration:Number):Number {
			var p:Number = 0;
			var a:Number = 0;
			var s:Number;			
			if (change!=0)
			switch(transition) {
				//linear equation
				case "linear":
					return change * time / duration + init;
				break;	
				case "easeInCubic":
					return change * Math.pow (time/duration, 3) + init;
				break;
				case "easeOutCubic":
					return change * (Math.pow (time/duration-1, 3) + 1) + init;
				break;
				case "easeInOutCubic":
					if ((time/=duration/2) < 1)
						return change/2 * Math.pow (time, 3) + init;
					return change/2 * (Math.pow (time-2, 3) + 2) + init;
				break;
				case "easeInQuart":
					return change * Math.pow (time/duration, 4) + init;
				break;
				case "easeOutQuart":
					return -change * (Math.pow (time/duration-1, 4) - 1) + init;
				break;
				case "easeInOutQuart":
					if ((time/=duration/2) < 1)
						return change/2 * Math.pow (time, 4) + init;
					return -change/2 * (Math.pow (time-2, 4) - 2) + init;
				break;
				case "easeInQuint":
					return change * Math.pow (time/duration, 5) + init;
				break;
				case "easeOutQuint":
					return change * (Math.pow (time/duration-1, 5) + 1) + init;
				break;
				case "easeInOutQuint":
					if ((time/=duration/2) < 1)
						return change/2 * Math.pow (time, 5) + init;
					return change / 2 * (Math.pow (time - 2, 5) + 2) + init;
				break;
				case "easeInSine":
					return change * (1 - Math.cos(time/duration * (Math.PI/2))) + init;
				break;
				case "easeOutSine":
					return change * Math.sin(time/duration * (Math.PI/2)) + init;
				break;
				case "easeInOutSine":
					return change/2 * (1 - Math.cos(Math.PI*time/duration)) + init;
				break;
				case "easeInExpo":
					return change * Math.pow(2, 10 * (time/duration - 1)) + init;
				break;
				case "easeOutExpo":
					return change * (-Math.pow(2, -10 * time/duration) + 1) + init;
				break;
				case "easeInOutExpo":
					if ((time/=duration/2) < 1)
						return change/2 * Math.pow(2, 10 * (time - 1)) + init;
					return change/2 * (-Math.pow(2, -10 * --time) + 2) + init;
				break;
				case "easeInCirc":
					return change * (1 - Math.sqrt(1 - (time/=duration)*time)) + init;
				break;
				case "easeOutCirc":
					return change * Math.sqrt(1 - (time=time/duration-1)*time) + init;
				break;
				case "easeInOutCirc":
					if ((time/=duration/2) < 1)
						return change/2 * (1 - Math.sqrt(1 - time*time)) + init;
					return change/2 * (Math.sqrt(1 - (time-=2)*time) + 1) + init;
				break;
				case "easeInBounce":
					return change - tweenEquations.calculateEquation("easeOutBounce", duration-time, 0, change, duration) + init;					
				break;
				case "easeOutBounce":
					if ((time/=duration) < (1/2.75)) {
						return change*(7.5625*time*time) + init;
					} else if (time < (2/2.75)) {
						return change*(7.5625*(time-=(1.5/2.75))*time + .75) + init;
					} else if (time < (2.5/2.75)) {
						return change*(7.5625*(time-=(2.25/2.75))*time + .9375) + init;
					} else {
						return change*(7.5625*(time-=(2.625/2.75))*time + .984375) + init;
					}
				break;
				case "easeInOutBounce":
					if (time < duration/2) return tweenEquations.calculateEquation("easeInBounce",time*2, 0, change, duration) * .5 + init;
					else return tweenEquations.calculateEquation("easeOutBounce",time*2-duration, 0, change, duration) * .5 + change*.5 + init;
				break;
				case "easeInElastic":
					if (time==0) return init;  if ((time/=duration)==1) return init+change;  if (!p) p=duration*.3;
					if (!a || a < Math.abs(change)) { a=change; s=p/4; }
					else s = p/(2*Math.PI) * Math.asin (change/a);
					return -(a*Math.pow(2,10*(time-=1)) * Math.sin( (time*duration-s)*(2*Math.PI)/p )) + init;
				break;
				case "easeOutElastic":
					if (time==0) return init;  if ((time/=duration)==1) return init+change;  if (!p) p=duration*.3;
					if (a < Math.abs(change)) { a=change; s=p/4; }
					else s = p/(2*Math.PI) * Math.asin (change/a);
					return a*Math.pow(2,-10*time) * Math.sin( (time*duration-s)*(2*Math.PI)/p ) + change + init;
				break;
				case "easeInOutElastic":
					if (time==0) return init;  if ((time/=duration/2)==2) return init+change;  if (!p) p=duration*(.3*1.5);
					if (a < Math.abs(change)) { a=change; s=p/4; }
					else s = p/(2*Math.PI) * Math.asin (change/a);
					if (time < 1) return -.5*(a*Math.pow(2,10*(time-=1)) * Math.sin( (time*duration-s)*(2*Math.PI)/p )) + init;
					return a*Math.pow(2,-10*(time-=1)) * Math.sin( (time*duration-s)*(2*Math.PI)/p )*.5 + change + init;
				break;
				case "easeInBack":
					s = 1.70158;
					return change*(time/=duration)*time*((s+1)*time - s) + init;
				break;
				case "easeOutBack":
					s = 1.70158;
					return change*((time=time/duration-1)*time*((s+1)*time + s) + 1) + init;
				break;
				case "easeInOutBack":
					s = 1.70158;
					if ((time/=duration/2) < 1) return change/2*(time*time*(((s*=(1.525))+1)*time - s)) + init;
					return change/2*((time-=2)*time*(((s*=(1.525))+1)*time + s) + 2) + init;
				break;
			}
			return init;	
		}
		public static function get linear():String {
			return "linear";
		}
		public static function get easeInCubic():String {
			return "easeInCubic";
		}		
		public static function get easeOutCubic():String {
			return "easeOutCubic";
		}		
		public static function get easeInOutCubic():String {
			return "easeInOutCubic";
		}	
		public static function get easeInQuart():String {
			return "easeInQuart";
		}		
		public static function get easeOutQuart():String {
			return "easeOutQuart";
		}		
		public static function get easeInOutQuart():String {
			return "easeInOutQuart";
		}		
		public static function get easeInQuint():String {
			return "easeInQuint";
		}		
		public static function get easeOutQuint():String {
			return "easeOutQuint";
		}		
		public static function get easeInOutQuint():String {
			return "easeInOutQuint";
		}		
		public static function get easeInSine():String {
			return "easeInSine";
		}		
		public static function get easeOutSine():String {
			return "easeOutSine";
		}		
		public static function get easeInOutSine():String {
			return "easeInOutSine";
		}		
		public static function get easeInCirc():String {
			return "easeInCirc";
		}		
		public static function get easeOutCirc():String {
			return "easeOutCirc";
		}		
		public static function get easeInOutCirc():String {
			return "easeInOutCirc";
		}		
		public static function get easeInExpo():String {
			return "easeInExpo";
		}		
		public static function get easeOutExpo():String {
			return "easeOutExpo";
		}		
		public static function get easeInOutExpo():String {
			return "easeInOutExpo";
		}		
		public static function get easeInBounce():String {
			return "easeInBounce";
		}		
		public static function get easeOutBounce():String {
			return "easeOutBounce";
		}		
		public static function get easeInOutBounce():String {
			return "easeInOutBounce";
		}		
		public static function get easeInElastic():String {
			return "easeInElastic";
		}		
		public static function get easeOutElastic():String {
			return "easeOutElastic";
		}		
		public static function get easeInOutElastic():String {
			return "easeInOutElastic";
		}	
		public static function get easeInBack():String {
			return "easeInBack";
		}
		public static function get easeOutBack():String {
			return "easeOutBack";
		}
		public static function get easeInOutBack():String {
			return "easeInOutBack";
		}		
	}
}